﻿using FluentAssertions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using NewRetail.Application.Components.Warehouse;
using NewRetail.Application.Components.Warehouse.Entity;
using NewRetail.Application.Core;
using System;
using System.Linq;
using System.Threading.Tasks;
using Volo.Abp;
using Volo.Abp.Application.Dtos;

namespace NewRetail.Api.Controllers
{
    [NewRetailRoute("wholesale-inout")]
    public class WholeSaleInOutController : ReceiptsBaseController<WholesaleInOut, QueryInOutPagingDto>
    {
        private readonly IWholesaleService wholesaleService;
        private readonly IWarehouseGoodsService warehouseGoodsService;

        public WholeSaleInOutController(
            IWholesaleService wholesaleService,
            IWarehouseGoodsService warehouseGoodsService)
        {
            this.wholesaleService = wholesaleService;
            this.warehouseGoodsService = warehouseGoodsService;
        }

        protected override async Task<IQueryable<WholesaleInOut>> FilterQueryPaging(DbContext db, IQueryable<WholesaleInOut> query, QueryInOutPagingDto dto)
        {
            if (dto.InOrOut != null)
            {
                query = query.Where(x => x.inOrOut == dto.InOrOut.Value);
            }
            if (!string.IsNullOrWhiteSpace(dto.warehouseId))
            {
                query = query.Where(x => x.warehouseID == dto.warehouseId);
            }

            query = query.WhereIf(!string.IsNullOrWhiteSpace(dto.customerId), x => x.customerID == dto.customerId);

            if (dto.isAuditing != null)
            {
                query = query.Where(x => x.isAuditing == dto.isAuditing.Value);
            }
            if (dto.priceType != null)
            {
                query = query.Where(x => x.priceType == dto.priceType.Value);
            }
            query = query.WhereIf(dto.startTime != null, x => x.receiptDate >= dto.startTime.Value);
            query = query.WhereIf(dto.endTime != null, x => x.receiptDate < dto.endTime.Value);
            await Task.CompletedTask;
            return query;
        }

        [HttpPost("query-statistics-summary")]
        public async Task<ResponseEntity<QueryInOutSummaryGroupResult[]>> QueryStatisticsSummary([FromBody] QueryInOutSummaryGroupDto dto)
        {
            var data = await this.wholesaleService.QueryStatisticsSummary(dto);
            return new ResponseEntity<QueryInOutSummaryGroupResult[]>().SetData(data);
        }

        [HttpPost("query-statistics-detail")]
        public async Task<ResponseEntity<QueryInOutDetailGroupResult[]>> QueryStatisticsDetail([FromBody] QueryInOutDetailGroupDto dto)
        {
            var data = await this.wholesaleService.QueryStatisticsDetail(dto);
            return new ResponseEntity<QueryInOutDetailGroupResult[]>().SetData(data);
        }

        public override async Task<ResponseEntity<PagedResultDto<WholesaleInOut>>> QueryPaging([FromBody] QueryInOutPagingDto dto)
        {
            var res = await base.QueryPaging(dto);

            if (res?.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.wholesaleService.AttachWarehouse(res.Data.Items.ToArray());
                res.Data.Items = await this.wholesaleService.AttachCustomer(res.Data.Items.ToArray());
                res.Data.Items = await this.wholesaleService.AttachGoodsInfo(res.Data.Items.ToArray());
            }

            return res;
        }

        [HttpPost("add-multiple"), Obsolete]
        public async Task<ResponseEntity<WholesaleInOut[]>> AddMultiple([FromBody] WholesaleInOut[] data)
        {
            data.Should().NotBeNullOrEmpty();
            var no = await this.NoGeneratorService.GenerateReceiptNoAsync("PF");
            foreach (var m in data)
            {
                this.EntityHelper.InitEntity(m);
                m.receiptNo = no;
                m.isAuditing = false;
            }

            await this.Repo.InsertManyAsync(data, autoSave: true);

            return new ResponseEntity<WholesaleInOut[]>().SetData(data);
        }

        [HttpPost("save-multiple")]
        public async Task<ResponseEntity<WholesaleInOut[]>> SaveMultiple([FromBody] ReceiptNoItemsDto<WholesaleInOut> data)
        {
            var res = await this.Repo.SaveReceiptItems(this.HttpContext.RequestServices, data, "PF");
            return new ResponseEntity<WholesaleInOut[]>().SetData(res.Items);
        }

        [HttpPost("query-by-receipt-no")]
        public async Task<ResponseEntity<WholesaleInOut[]>> QueryByReceiptNo([FromBody] ReceiptNoDto dto)
        {
            dto.Should().NotBeNull();
            dto.receiptNo.Should().NotBeNullOrEmpty();
            var query = this.SingleStoreService.ApplyToQueryable(this.Repo);
            var data = await query.Where(x => x.receiptNo == dto.receiptNo).ToArrayAsync();

            data = await this.wholesaleService.AttachGoodsInfo(data);
            data = await this.wholesaleService.AttachCustomer(data);
            data = await this.wholesaleService.AttachWarehouse(data);

            return new ResponseEntity<WholesaleInOut[]>().SetData(data);
        }

        protected override async Task OnChangeApprovementStatus(DbContext db, WholesaleInOut item)
        {
            var warehouseGoods = await db.Set<WarehouseGoods>()
                .Where(x => x.warehouseID == item.warehouseID && x.goodsID == item.goodsID)
                .FirstOrDefaultAsync();

            var createNewWarehouseGoods = false;

            if (warehouseGoods == null)
            {
                //如果当前门店没有关联商品，入库时则自动关联
                createNewWarehouseGoods = true;
                warehouseGoods = new WarehouseGoods()
                {
                    goodsID = item.goodsID,
                    warehouseID = item.warehouseID
                };
                this.EntityHelper.InitEntity(warehouseGoods);
            }

            if (item.isAuditing)
            {
                if (item.IsInWarehouse())
                {
                    //同意退货
                    warehouseGoods.goodsNum += item.quantity;
                }
                else
                {
                    //同意批发
                    warehouseGoods.goodsNum -= item.quantity;
                }
            }
            else
            {
                if (item.IsInWarehouse())
                {
                    //撤销退货
                    warehouseGoods.goodsNum -= item.quantity;
                }
                else
                {
                    //撤销批发
                    warehouseGoods.goodsNum += item.quantity;
                }
            }

            if (createNewWarehouseGoods)
            {
                db.Set<WarehouseGoods>().Add(warehouseGoods);
            }
        }

        #region 每条批发销售单只显示一条记录 add by cl 2024.04.30
        /// <summary>
        /// 每条批发销售单只显示一条记录
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [HttpPost("query-paging-distinct")]
        public async Task<ResponseEntity<PagedResultDto<WholesaleInOut>>> QueryPagingDistinct([FromBody] QueryInOutPagingDto dto)
        {
            var query = await base.GetQueryPagingData(dto);
            var data = new PagedResultDto<WholesaleInOut>();
            query = await this.OrderQueryPaging(query, dto);

            query = query.WhereIf(dto.startTime != null, x => x.receiptDate >= dto.startTime.Value);
            query = query.WhereIf(dto.endTime != null, x => x.receiptDate < dto.endTime.Value);

            var list = query?.ToList()?.GroupBy(g => new { g.receiptDate, g.receiptNo, g.warehouseID, g.customerID, g.inOrOut, g.priceType })
                .Select(x => new WholesaleInOut
                {
                    receiptDate = x.Key.receiptDate,
                    receiptNo = x.Key.receiptNo,
                    warehouseID = x.Key.warehouseID,
                    customerID = x.Key.customerID,
                    inOrOut = x.Key.inOrOut,
                    priceType = x.Key.priceType,
                    quantity = x.Sum(s => s.quantity),
                    price = x.Sum(s => s.price * s.quantity),
                    discountAmountMst = x.Average(s => s.discountAmountMst),
                    isAuditing = x.Select(a => a.isAuditing).FirstOrDefault(),
                    operateTime = x.Select(a => a.operateTime).FirstOrDefault()
                }).ToList();

            data.TotalCount = list.Count();
            //logger.LogInformation(">>>>>>>>>>>>>>>>>>TotalCount：" + data.TotalCount);
            list = list.Skip((dto.Page - 1) * dto.PageSize).Take(dto.PageSize).ToList();
            //logger.LogInformation(">>>>>>>>>>>>>>>>>>5");
            data.Items = list.ToArray();
            ResponseEntity<PagedResultDto<WholesaleInOut>> res = new ResponseEntity<PagedResultDto<WholesaleInOut>>().SetData(data);

            if (res.Data?.Items?.Any() ?? false)
            {
                res.Data.Items = await this.wholesaleService.AttachCustomer(res.Data.Items.ToArray());
                res.Data.Items = await this.wholesaleService.AttachWarehouse(res.Data.Items.ToArray());
            }

            return res;
        }
        #endregion

        #region add by cl 20240513
        /// <summary>
        /// 整单删除得根据receiptNo找到id
        /// </summary>
        /// <param name="ids">receiptNo数组</param>
        /// <returns></returns>
        protected override async Task<string[]> BeforeDelete(string[] ids)
        {
            string[] delIds = null;

            if (ids.Length > 0)
            {
                var query = this.SingleStoreService.ApplyToQueryable(this.Repo);
                //找出未审核的单据
                delIds = await query.Where(g => ids.Contains(g.receiptNo) && g.isAuditing == false).Select(g => g.Id).Distinct().ToArrayAsync();
            }
            if (delIds.Length == 0)
            {
                throw new UserFriendlyException("没有要删除的记录！");
            }

            return delIds;
        }
        #endregion
    }
}
